
#ifndef __RENDERLIST_H__
#define __RENDERLIST_H__

#include "MetaGraph.h"
#include "3dModelDef.h"
#include "3dCamera.h"
#include "Obj4d.h"

// flags for sorting algorithm
#define SORT_POLYLIST_AVGZ  0  // sorts on average of all vertices
#define SORT_POLYLIST_NEARZ 1  // sorts on closest z vertex of each poly
#define SORT_POLYLIST_FARZ  2  // sorts on farthest z vertex of each poly


class CRenderList
{
public:

	CRenderList()
	{
		state	= 0;
		attr	= 0;

		num_polys = 0; // that was hard!

		memset(poly_ptrs, 0, sizeof(poly_ptrs));
		memset(poly_data, 0, sizeof(poly_data));

		m_pCam	= NULL;
	}

	virtual ~CRenderList()
	{

	}

	int Init(uint8 *video_buffer, int lpitch, RECT clipRect, C3dCamera* pCam)
	{
		m_pCam	= pCam;
		m_graphLine.Init(video_buffer, lpitch, clipRect);
		m_graphTrig.Init(video_buffer, lpitch, clipRect);

		return 0;
	}

	//consider there are many camera,so maybe need a camera list
	int SetCamera(C3dCamera* pCam)
	{
		m_pCam	= pCam;
		return 0;
	}

	int Reset()
	{
		// this function intializes and resets the sent render list and
		// redies it for polygons/faces to be inserted into it
		// note that the render list in this version is composed
		// of an array FACE4DV1 pointer objects, you call this
		// function each frame

		// since we are tracking the number of polys in the
		// list via num_polys we can set it to 0
		// but later we will want a more robust scheme if
		// we generalize the linked list more and disconnect
		// it from the polygon pointer list
		num_polys = 0; // that was hard!

		state	= 0;
		attr	= 0;

		return 0;

	}  // Reset

	int Transform(CMatrix44& mt,		// transformation matrix
				  int coord_select);    // selects coords to transform

	int Model_To_World(	CPoint4d& world_pos, 
						int coord_select = TRANSFORM_LOCAL_TO_TRANS );

	int World_To_Camera();

	int Camera_To_Perspective();

	int Convert_From_Homogeneous4D();

	int Perspective_To_Screen();

	int Camera_To_Perspective_Screen();

	int Insert_POLY4DV1(POLY4DV1_PTR poly);
	int Insert_POLYF4DV1(POLYF4DV1_PTR poly);
	int Insert_Obj4d(CObj4d& obj, int insert_local = 0, int lighting_on = 0);

	int Remove_Backfaces();

	int Draw_Wire16();
	int Draw_Solid16();

	int Sort(int sort_method);


	// object to hold the render list, this way we can have more
	// than one render list at a time
	int				state; // state of renderlist ???
	int				attr;  // attributes of renderlist ???

	// the render list is an array of pointers each pointing to 
	// a self contained "renderable" polygon face POLYF4DV1
	POLYF4DV1_PTR	poly_ptrs[RENDERLIST4DV1_MAX_POLYS];

	// additionally to cut down on allocatation, de-allocation
	// of polygons each frame, here's where the actual polygon
	// faces will be stored
	POLYF4DV1		poly_data[RENDERLIST4DV1_MAX_POLYS];

	int				num_polys; // number of polys in render list

protected:
	
	C3dCamera*		m_pCam;
	CGraphLine		m_graphLine;
	CGraphTrig		m_graphTrig;
};

#endif